package com.boot.ys.mybatisplus.utils;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.*;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.lang.StringUtils;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;


/**
 * http帮助类发起https或者http请求，
 * 方式有get或者post
 * 这个类是云南平安沃聚项目里面的
 * @author Administrator
 *
 *         这样子发起请求
 *         String s = HttpAUtil.executeGet(tokenUrl);
 *         System.out.println("测试"+s);
 *
 */
public class HttpAUtil {
    //超时时间毫秒
    private static final Integer CONNECTION_TIME_OUT = 20000;

    private static final String CHARSET = "UTF-8";

    /**
     * get通用请求方法
     * @param url
     * @return
     */
    public static String executeGet(String url){

        String result = "";

        if(url.startsWith("https")){
            result = httpsGet(url);
        }else{
            result = httpGet(url);
        }

        return result;
    }

    /**
     * post通用请求方法
     * @param url
     * @param param
     * @return
     */
    public static String executePost(String url,Map<String,String> param){
        String result = "";

        if(url.startsWith("https")){
            result = httpsPost(url,param);
        }else{
            result = httpPost(url,param);
        }

        return result;
    }


    public static String httpsPost(String url,String content){
        HttpClient client = new DefaultHttpClient();

        String result = "";
        X509TrustManager xtm = new X509TrustManager(){   //创建TrustManager
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
            public X509Certificate[] getAcceptedIssuers() { return null; }
        };

        SSLContext ctx;
        try {
            ctx = SSLContext.getInstance("TLS");
            ctx.init(null, new TrustManager[]{xtm}, null);

            //创建SSLSocketFactory
            SSLSocketFactory socketFactory = new SSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

            client.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, socketFactory));
            HttpPost post = new HttpPost(url);

            //创建参数队列
            post.setEntity(new StringEntity(content));

            //result = EntityUtils.toString(post.getEntity());
            HttpResponse httpResponse = client.execute(post);
            result = EntityUtils.toString(httpResponse.getEntity(),"UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println(e.getMessage());
        } finally{
            if(client!=null){
                client.getConnectionManager().shutdown();
            }
        }

        return result;
    }

    /**
     * get请求
     * @param url 请求地址
     * @return
     */
    public static String httpGet(String url){
        HttpClient client = new DefaultHttpClient();

        HttpGet post = new HttpGet(url);
        String result = "";
        try {
            HttpResponse res = client.execute(post);
            result = EntityUtils.toString(res.getEntity(),"utf-8");
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(client!=null){
                client.getConnectionManager().shutdown();
            }
        }
        return result;
    }

    /**
     * https get请求
     * @param url
     * @return
     */
    public static String httpsGet(String url){
        HttpClient client = new DefaultHttpClient();

        String result = "";
        X509TrustManager xtm = new X509TrustManager(){   //创建TrustManager
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
            public X509Certificate[] getAcceptedIssuers() { return null; }
        };

        SSLContext ctx;
        try {
            ctx = SSLContext.getInstance("TLS");
            ctx.init(null, new TrustManager[]{xtm}, null);

            //创建SSLSocketFactory
            SSLSocketFactory socketFactory = new SSLSocketFactory(ctx);
            client.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, socketFactory));
            HttpGet get = new HttpGet(url);
            HttpResponse httpResponse = client.execute(get);
            result = EntityUtils.toString(httpResponse.getEntity(),"UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if(client!=null){
                client.getConnectionManager().shutdown();
            }
        }

        return result;
    }

    /**
     * https post请求
     * @param url 请求地址
     * @param param 参数
     * @return
     */
    public static String httpsPost(String url,Map<String,String> param){
        HttpClient client = new DefaultHttpClient();

        client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, CONNECTION_TIME_OUT);
        client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, CONNECTION_TIME_OUT);

        String result = "";
        X509TrustManager xtm = new X509TrustManager(){   //创建TrustManager
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
            public X509Certificate[] getAcceptedIssuers() { return null; }
        };

        SSLContext ctx;
        try {
            ctx = SSLContext.getInstance("TLS");
            ctx.init(null, new TrustManager[]{xtm}, null);

            //创建SSLSocketFactory
            SSLSocketFactory socketFactory = new SSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

            client.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, socketFactory));
            HttpPost post = new HttpPost(url);

            //创建参数队列
            List<NameValuePair> formparams = new ArrayList<NameValuePair>();
            if(param!=null&&param.size()!=0){
                for (Map.Entry<String, String> set : param.entrySet()) {
                    String key = set.getKey();
                    String value = set.getValue()==null?"":set.getValue();
                    formparams.add(new BasicNameValuePair(key, value));
                }
            }

            post.setEntity(new UrlEncodedFormEntity(formparams, HTTP.UTF_8));

            //result = EntityUtils.toString(post.getEntity());
            HttpResponse httpResponse = client.execute(post);
            result = EntityUtils.toString(httpResponse.getEntity(),"UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            if(client!=null){
                client.getConnectionManager().shutdown();
            }
        }

        return result;
    }

    /**
     * https post请求
     * @param url 请求地址
     * @param param 参数
     * @return
     */
    public static String httpsPostV2(String url,Map<String,String> param){

        HttpClient client = getSecuredHttpClient(new DefaultHttpClient());
        String result = "";
        try {

            //创建参数队列
            List<NameValuePair> formparams = new ArrayList<NameValuePair>();
            if(param!=null&&param.size()!=0){
                for (Map.Entry<String, String> set : param.entrySet()) {
                    String key = set.getKey();
                    String value = set.getValue()==null?"":set.getValue();
                    formparams.add(new BasicNameValuePair(key, value));
                }
            }
            HttpPost post = new HttpPost(url);
            post.setEntity(new UrlEncodedFormEntity(formparams, HTTP.UTF_8));

            //result = EntityUtils.toString(post.getEntity());
            HttpResponse httpResponse = client.execute(post);
            result = EntityUtils.toString(httpResponse.getEntity(),"UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            if(client!=null){
                client.getConnectionManager().shutdown();
            }
        }

        return result;
    }

    private static DefaultHttpClient getSecuredHttpClient(HttpClient httpClient) {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            X509TrustManager tm = new X509TrustManager() {

                public void checkClientTrusted(X509Certificate[] chain,
                                               String authType) throws CertificateException
                {
                    // TODO Auto-generated method stub

                }

                public void checkServerTrusted(X509Certificate[] chain,
                                               String authType) throws CertificateException
                {
                    // TODO Auto-generated method stub

                }

                public X509Certificate[] getAcceptedIssuers()
                {
                    // TODO Auto-generated method stub
                    return null;
                }

            };
            ctx.init(null, new TrustManager[] { tm }, null);
            SSLSocketFactory ssf = new SSLSocketFactory(ctx);
            ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            ClientConnectionManager ccm = httpClient.getConnectionManager();
            SchemeRegistry sr = ccm.getSchemeRegistry();
            //设置要使用的端口，默认是443
            sr.register(new Scheme("https", ssf, 443));
            return new DefaultHttpClient(ccm, httpClient.getParams());
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    /**
     * https post请求
     * @param url 请求地址
     * @param param 参数
     * @return
     */
    public static String httpPost(String url,Map<String,String> param){

        DefaultHttpClient client = new DefaultHttpClient();
        client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, CONNECTION_TIME_OUT);
        client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, CONNECTION_TIME_OUT);
        String result = "";
        try {

            HttpPost post = new HttpPost(url);

            // 创建参数队列
            List<NameValuePair> formparams = new ArrayList<NameValuePair>();
            if(param!=null&&param.size()!=0){
                for (Map.Entry<String, String> set : param.entrySet()) {
                    String key = set.getKey();
                    String value = set.getValue()==null?"":set.getValue();
                    formparams.add(new BasicNameValuePair(key, value));
                }
            }

            post.setEntity(new UrlEncodedFormEntity(formparams, HTTP.UTF_8));

            //result = EntityUtils.toString(post.getEntity());

            HttpResponse httpResponse = client.execute(post);
            result = EntityUtils.toString(httpResponse.getEntity(),"UTF-8");
        } catch (Exception e) {

        } finally{
            if(client!=null){
                client.getConnectionManager().shutdown();
            }
        }

        return result;
    }


    /**
     * https post请求
     * @param url 请求地址
     * @return
     */
    public static String httpsPost(String url){

        HttpClient client = new DefaultHttpClient();

        String result = "";
        X509TrustManager xtm = new X509TrustManager(){   //创建TrustManager
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
            public X509Certificate[] getAcceptedIssuers() { return null; }
        };

        SSLContext ctx;
        try {
            ctx = SSLContext.getInstance("TLS");
            ctx.init(null, new TrustManager[]{xtm}, null);

            //创建SSLSocketFactory
            SSLSocketFactory socketFactory = new SSLSocketFactory(ctx);
            client.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, socketFactory));
            HttpPost post = new HttpPost(url);

            //result = EntityUtils.toString(post.getEntity());
            HttpResponse httpResponse = client.execute(post);
            result = EntityUtils.toString(httpResponse.getEntity(),"UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            if(client!=null){
                client.getConnectionManager().shutdown();
            }
        }

        return result;
    }



    /**
     * http post请求
     * @param url 请求地址
     * @return
     */
    public static String httpPost(String url){

        HttpClient client = new DefaultHttpClient();

        String result = "";

        try {
            HttpPost post = new HttpPost(url);
            //result = EntityUtils.toString(post.getEntity());
            HttpResponse httpResponse = client.execute(post);
            result = EntityUtils.toString(httpResponse.getEntity(),"UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            if(client!=null){
                client.getConnectionManager().shutdown();
            }
        }

        return result;
    }



    /**
     * json方式的https请求
     * @param url
     * @param content
     * @return
     */
    public static String httpsJsonPost(String url,String content){

        HttpClient client = new DefaultHttpClient();

        client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, CONNECTION_TIME_OUT);
        client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, CONNECTION_TIME_OUT);

        String result = "";
        X509TrustManager xtm = new X509TrustManager(){   //创建TrustManager
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
            public X509Certificate[] getAcceptedIssuers() { return null; }
        };

        SSLContext ctx;
        try {
            ctx = SSLContext.getInstance("TLS");
            ctx.init(null, new TrustManager[]{xtm}, null);

            //创建SSLSocketFactory
            SSLSocketFactory socketFactory = new SSLSocketFactory(ctx);
            client.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, socketFactory));
            HttpPost post = new HttpPost(url);

            StringEntity s = new StringEntity(content, "UTF-8");   // 中文乱码在此解决
            s.setContentType("application/json");
            post.setEntity(s);  //设置内容

            HttpResponse httpResponse = client.execute(post);

            result = EntityUtils.toString(httpResponse.getEntity(),"UTF-8");

        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            if(client!=null){
                client.getConnectionManager().shutdown();
            }
        }

        return result;
    }

    /**
     * json方式的https请求
     * @param url
     * @param content 请求内容
     * @param head 请求头信息
     * @return
     */
    public static String httpsJsonPost(String url,String content,Map<String,String> head){

        HttpClient client = new DefaultHttpClient();

        String result = "";
        X509TrustManager xtm = new X509TrustManager(){   //创建TrustManager
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
            public X509Certificate[] getAcceptedIssuers() { return null; }
        };

        SSLContext ctx;
        try {
            ctx = SSLContext.getInstance("TLS");
            ctx.init(null, new TrustManager[]{xtm}, null);

            //创建SSLSocketFactory
            SSLSocketFactory socketFactory = new SSLSocketFactory(ctx);
            client.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, socketFactory));
            HttpPost post = new HttpPost(url);
            StringEntity s = new StringEntity(content, "UTF-8");   // 中文乱码在此解决
            s.setContentType("application/json");
            post.setEntity(s);  //设置内容

            //设置head
            if(head!=null&&head.size()!=0){
                Object[] attr = head.keySet().toArray();
                for(Object obj:attr){
                    String key = String.valueOf(obj);
                    String value = head.get(String.valueOf(obj));
                    post.addHeader(key,value);
                }
            }

            HttpResponse httpResponse = client.execute(post);

            result = EntityUtils.toString(httpResponse.getEntity(),"UTF-8");

        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            if(client!=null){
                client.getConnectionManager().shutdown();
            }
        }

        return result;
    }

    public static String doPostQueryCmd(String strURL, String req) {
        String result = null;
        BufferedReader in = null;
        BufferedOutputStream out = null;
        try {
            URL url = new URL(strURL);
            URLConnection con = url.openConnection();
            HttpURLConnection httpUrlConnection  =  (HttpURLConnection) con;
            httpUrlConnection.setConnectTimeout(10000);
            httpUrlConnection.setReadTimeout(10000);
            httpUrlConnection.setRequestMethod("POST");
            con.setUseCaches(false);
            con.setDoInput(true);
            con.setDoOutput(true);
            out = new BufferedOutputStream(con.getOutputStream());
            byte outBuf[] = req.getBytes("utf-8");
            out.write(outBuf);
            out.close();

            in = new BufferedReader(new InputStreamReader(con.getInputStream(),"UTF-8"));
            StringBuffer sb = new StringBuffer();
            String data = null;

            while ((data = in.readLine()) != null) {
                sb.append(data);
            }


            result = sb.toString();

        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                }
            }
        }
        if (result == null)
            return "";
        else
            return result;
    }



    /**
     * json方式的http请求
     * @param url
     * @param content 请求内容
     * @return
     */
    public static String httpJsonPost(String url,String content){

        HttpClient client = new DefaultHttpClient();

        String result = "";

        try {
            HttpPost post = new HttpPost(url);
            StringEntity s = new StringEntity(content, "UTF-8");   // 中文乱码在此解决
            s.setContentType("application/json");
            post.setEntity(s);  //设置内容
            HttpResponse httpResponse = client.execute(post);
            result = EntityUtils.toString(httpResponse.getEntity(),"UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            if(client!=null){
                client.getConnectionManager().shutdown();
            }
        }

        return result;
    }

    /**
     * json提交
     * @return
     */
    public static String executePostJSON(String url,String content){
        String result = "";

        if(url.startsWith("https")){
            result = httpsJsonPost(url,content);
        }else{
            result = httpJsonPost(url,content);
        }

        return result;
    }

    /**
     * 上传图片
     * @param url
     * @param map
     * @param files
     * @return
     * @throws Exception
     */
    public static String httpPostFile(String url,Map<String, String> map, LinkedHashMap<String, File> files) throws Exception{
        try {
            if(StringUtils.isEmpty(url) || null == map || map.isEmpty()){
                return null;
            }
            //创建POST请求
            HttpPost post = new HttpPost(url);

            MultipartEntity entity = new MultipartEntity();
            //请求参数
            for(String key : map.keySet()){
                entity.addPart(key, new StringBody(map.get(key), Charset.forName("UTF-8")));
            }

            for (String key : files.keySet()){
                entity.addPart(key,new FileBody(files.get(key)));
            }


            post.setEntity(entity);

            //发送请求
            HttpClient client = new DefaultHttpClient();
            HttpResponse response = client.execute(post);
            if(response.getStatusLine().getStatusCode() != HttpStatus.SC_OK){
                throw new Exception("请求失败！");
            }

            HttpEntity resEntity = response.getEntity();
            return null == resEntity ? "" : EntityUtils.toString(resEntity,CHARSET);
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception(e.getMessage());
        }
    }


    /**
     * 配置忽略SSL认证
     *
     * @param clientBuilder
     */
    public static void configureHttpClient(HttpClientBuilder clientBuilder) throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
            @Override
            public boolean isTrusted(X509Certificate[] x509Certificates, String s) {
                return true;
            }
        }).build();
        //NoopHostNameVerifer 接受任何有效的SSL会话来匹配目标主机
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
        clientBuilder.setSSLSocketFactory(sslsf);
    }

    /**
     * @param url         请求地址
     * @param reqeust     请求参数
     * @param isVerifySSL 是否开启SSl认证
     * @return
     * @throws IOException
     */
    public static String sendHttpPostRequest(String url, String reqeust, boolean isVerifySSL) throws IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException {

        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        if (!isVerifySSL)
            configureHttpClient(httpClientBuilder);
        HttpClient httpClient = httpClientBuilder.build();
/*        byte b[] = new byte[4];
        b[0] = new Integer(10).byteValue();
        b[1] = new Integer(211).byteValue();
        b[2] = new Integer(55).byteValue();
        b[3] = new Integer(2).byteValue();*/

        StringEntity requestEntity = new StringEntity(reqeust, "utf-8");
        HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader("content-type", "application/json;charset=UTF-8");
        httpPost.addHeader("Accept", "application/json");
        httpPost.setEntity(requestEntity);
     /*   httpPost.setConfig(RequestConfig.custom()
                .setLocalAddress(InetAddress.getByAddress(b))
                .build());*/
        HttpResponse httpResponse = httpClient.execute(httpPost);
        HttpEntity httpEntity = httpResponse.getEntity();
        InputStream inputStream = httpEntity.getContent();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String s;
        StringBuilder stringBuilder = new StringBuilder();
        while ((s = bufferedReader.readLine()) != null) {
            stringBuilder.append(s);
        }
        return stringBuilder.toString();
    }
}
